<!--
 * @description: el-segmented 组件
 * @fileName: index
 * @author: 17076
 * @date: 2025/3/19-上午9:38
 * @version: V1.0.0
-->

<template>
  <div class="el-segment">
    <div ref="wrapper" class="el-segment__wrapper">
      <div
        v-for="(item, index) in options"
        :key="index"
        class="el-segment-item"
        :class="{
          'is-active': modelValue === item[extraOption['value']],
          'is-disabled': item.disabled
        }"
        @click="handleClick(item)"
      >
        <i v-if="item.icon && item.icon.indexOf('el-') !== -1" :class="item.icon" style="margin-right: 8px"/>
        <svg-icon v-else-if="item.icon" :icon-class="item.icon" style="margin-right: 8px"/>
        <span class="etc el-segment-item__text">{{ item[extraOption['label']] }}</span>
      </div>
      <div v-if="showExtra" class="el-segment-extra">
        <slot name="extra">
          <span @click="() => { $emit('more') }">自定义<i class="el-icon-arrow-right" style="margin-left: 8px"/></span>
        </slot>
      </div>
      <div
        class="el-segment__indicator"
        :style="indicatorStyle"
      />
    </div>
  </div>
</template>

<script>
export default {
  name: 'SegmentController',
  props: {
    value: [String, Number],
    options: {
      type: Array,
      required: true
    },
    disabled: Boolean,
    // 显示额外的按钮，用于添加新的选项
    showExtra: Boolean,
    // 配置项
    extraOption: {
      type: Object,
      default: () => { return { label: 'label', value: 'value' } }
    }
  },
  data() {
    return {
      indicatorWidth: 0,
      indicatorOffset: 0
    }
  },
  computed: {
    modelValue: {
      get() { return this.value },
      set(val) { this.$emit('input', val) }
    },
    indicatorStyle() {
      return {
        width: `${this.indicatorWidth - this.indicatorOffset * 2}px`,
        transform: `translateX(${this.indicatorOffset}px)`
      }
    }
  },
  watch: {
    value: {
      immediate: true,
      handler: 'updateIndicator'
    }
  },
  mounted() {
    this.updateIndicator()
    window.addEventListener('resize', this.updateIndicator)
  },
  beforeDestroy() {
    window.removeEventListener('resize', this.updateIndicator)
  },
  methods: {
    handleClick(item) {
      if (this.disabled || item.disabled) return
      this.modelValue = item[this.extraOption['value']]
      this.$emit('change', item[this.extraOption['value']])
    },
    updateIndicator() {
      this.$nextTick(() => {
        const activeIndex = this.options.findIndex(i => i[this.extraOption['value']] === this.modelValue)
        if (activeIndex === -1) return

        const wrapper = this.$refs.wrapper
        const items = wrapper.querySelectorAll('.el-segment-item')
        const activeItem = items[activeIndex]

        this.indicatorWidth = activeItem.offsetWidth
        this.indicatorOffset = activeItem.offsetLeft
      })
    }
  }
}
</script>

<style scoped lang="scss">
.el-segment {
  display: inline-block;
  position: relative;
  user-select: none;
  width: 100%;
}

.el-segment__wrapper {
  position: relative;
  display: inline-flex;
  border-radius: 5px;
  background: #272C36;
  padding: 2px;
  box-sizing: border-box;
  width: 100%;
}

.el-segment-item {
  position: relative;
  flex: 1;
  //min-width: 50px;
  color: #FFFFFF;
  padding: 0 8px;
  min-height: 36px;
  line-height: 36px;
  cursor: pointer;
  transition: all 0.3s cubic-bezier(0.645, 0.045, 0.355, 1);
  border-radius: 5px;
  text-align: center;
  z-index: 1;
}
.el-segment-extra {
  min-height: 36px;
  line-height: 36px;
  padding: 0 8px;
  box-sizing: border-box;
  color: #5C6872;
  text-align: center;
  cursor: pointer;
  font-size: 12px;
}

.el-segment-item:hover:not(.is-active):not(.is-disabled) {
  background-color: rgba(255,255,255,0.5);
}

.el-segment-item.is-active {
  color: $base-color-default;
}

.el-segment-item.is-disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.el-segment__indicator {
  position: absolute;
  height: calc(100% - 4px);
  background: #333B4A;
  border-radius: 5px;
  box-shadow: 0 2px 4px rgba(0,0,0,0.1);
  transition: all 0.3s cubic-bezier(0.645, 0.045, 0.355, 1);
  top: 2px;
  left: 2px;
}
</style>
